package cn.wen.java.lang;

import java.util.Arrays;

/**
 * Title：对象工具类
 * <p>
 * Description：
 * <p>
 * Copyright：Copyright (c) 2010-2012
 * 
 * @author <a href="mailto:ct_wen@qq.com">ctwen</a>, 温承瑭
 * @version Revision：1.0 Date：2011/2/12 Description：初完成。
 *          <p>
 * @see org.apache.commons.lang.ObjectUtils
 */
public abstract class HelperOfObject {

    // -----------------------------------------------------------------------
    // Equals
    // -----------------------------------------------------------------------

    /**
     * <p>
     * Compares two objects for equality, where either one or both objects may be <code>null</code>.
     * 
     * <pre>
     * HelperOfObject.equals(null, null)                  = true
     * HelperOfObject.equals(null, "")                    = false
     * HelperOfObject.equals("", null)                    = false
     * HelperOfObject.equals("", "")                      = true
     * HelperOfObject.equals(Boolean.TRUE, null)          = false
     * HelperOfObject.equals(Boolean.TRUE, "true")        = false
     * HelperOfObject.equals(Boolean.TRUE, Boolean.TRUE)  = true
     * HelperOfObject.equals(Boolean.TRUE, Boolean.FALSE) = false
     * </pre>
     * <p>
     * Compares arrays with <code>Arrays.equals</code>, 
     * performing an equality check based on the array elements rather than the
     * array reference.
     * 
     * @param o1 the first object, may be <code>null</code>
     * @param o2 the second object, may be <code>null</code>
     * @return <code>true</code> if the values of both objects are the same
     */
    public static boolean equals(Object o1, Object o2) {
	if (o1 == o2) {
	    return true;
	}
	if ((o1 == null) || (o2 == null)) {
	    return false;
	}
	if (o1.equals(o2)) {
	    return true;
	}
	if (o1.getClass().isArray() && o2.getClass().isArray()) {
	    if (o1 instanceof Object[] && o2 instanceof Object[]) {
		return Arrays.equals((Object[]) o1, (Object[]) o2);
	    }
	    if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
		return Arrays.equals((boolean[]) o1, (boolean[]) o2);
	    }
	    if (o1 instanceof byte[] && o2 instanceof byte[]) {
		return Arrays.equals((byte[]) o1, (byte[]) o2);
	    }
	    if (o1 instanceof char[] && o2 instanceof char[]) {
		return Arrays.equals((char[]) o1, (char[]) o2);
	    }
	    if (o1 instanceof double[] && o2 instanceof double[]) {
		return Arrays.equals((double[]) o1, (double[]) o2);
	    }
	    if (o1 instanceof float[] && o2 instanceof float[]) {
		return Arrays.equals((float[]) o1, (float[]) o2);
	    }
	    if (o1 instanceof int[] && o2 instanceof int[]) {
		return Arrays.equals((int[]) o1, (int[]) o2);
	    }
	    if (o1 instanceof long[] && o2 instanceof long[]) {
		return Arrays.equals((long[]) o1, (long[]) o2);
	    }
	    if (o1 instanceof short[] && o2 instanceof short[]) {
		return Arrays.equals((short[]) o1, (short[]) o2);
	    }
	}
	return false;
    }

    // -----------------------------------------------------------------------
    // HashCode
    // -----------------------------------------------------------------------

    /**
     * <p>
     * Gets the hash code of an object returning zero when the object is <code>null</code>.
     * </p>
     * 
     * <pre>
     * HelperOfObject.hashCode(null)   = 0
     * HelperOfObject.hashCode(obj)    = obj.hashCode()
     * </pre>
     * 
     * @param obj the object to obtain the hash code of, may be <code>null</code>
     * @return the hash code of the object, or zero if null
     */
    public static int hashCode(Object obj) {
	return (obj == null) ? 0 : obj.hashCode();
    }

    // -----------------------------------------------------------------------
    // ToString
    // -----------------------------------------------------------------------

    /**
     * <p>
     * Gets the <code>toString</code> of an <code>Object</code> 
     * returning an empty string ("") if <code>null</code> input.
     * </p>
     * 
     * <pre>
     * HelperOfObject.toString(null)         = ""
     * HelperOfObject.toString("")           = ""
     * HelperOfObject.toString("bat")        = "bat"
     * HelperOfObject.toString(Boolean.TRUE) = "true"
     * </pre>
     * 
     * @see String#valueOf(Object)
     * @param obj the Object to <code>toString</code>, may be null
     * @return the passed in Object's toString, or nullStr if <code>null</code> input
     */
    public static String toString(Object obj) {
	return obj == null ? "" : obj.toString();
    }

}
